package com.qinyeit.codegen;
import com.google.common.base.CaseFormat;
import com.qinyeit.codegen.entity.PropConfig;
import com.qinyeit.codegen.entity.Table;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;

public class MainFrame extends JFrame implements ActionListener {
    private Logger log=Logger.getLogger(MainFrame.class);
    private static final long serialVersionUID = 1L;

    private JTextArea area=null;

   private JPanel textPanel=new JPanel();

    private JPanel savePathPanel=new JPanel();

    private JScrollPane editSqlPanel=new JScrollPane();
    private JPanel operationPanel=new JPanel();

    private JButton btn;
    private JCheckBox selectAllBox = null;
    private Font font;

    private JCheckBox entityBox = null;
    private JCheckBox repositoryBox = null;
    private JCheckBox serviceBox = null;
    private JCheckBox serviceImplBox = null;
    private JCheckBox controllerBox = null;
    private JCheckBox serviceTestBox = null;
    private JCheckBox controllerTestBox = null;
    private JCheckBox viewBox = null;
    private JCheckBox modalBox = null;
    private JCheckBox treeBox = null;

    private JTextField authorText = null;
    private JTextField moduleText = null;
    private JComboBox<String> entry=null;//入口


    private JLabel tips = null;

    private JTextField filePathText = null;
    private JButton bowserDirBtn = null;

    private JTextField tableNameText = null;
    private JButton deleteTableBtn = null;

    private JPanel checkBoxPanel = null;

    private int width=900;
    public MainFrame() {

        this.font = new Font("宋体", Font.PLAIN, 12);
        this.setTitle("代码生成器");
        this.setSize(width, 600);
        this.setResizable(false);
        this.getContentPane().setLayout(new BorderLayout(10,5));
        this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        JPanel rootContainer=new JPanel();
        rootContainer.setSize(width,600);
        this.add(rootContainer,BorderLayout.CENTER);
        rootContainer.add(textPanel);

        checkBoxPanel = new JPanel();
        rootContainer.add(checkBoxPanel); //选择复选框
        rootContainer.add(savePathPanel); //路径选择
        rootContainer.add(editSqlPanel); //SQL文本
        rootContainer.add(operationPanel); //操作
        initLayout();
    }

    /**
     * 初始化菜单布局
     */
    private void initMenuBar() {
        JMenuBar menuBar = new JMenuBar();

        Map<String, String[]> map = new LinkedHashMap<>();
        map.put("File", new String[]{"Restart"});
        map.put("Edit", new String[]{"Setting"});
        map.put("Help", new String[]{"About"});

        JMenu menu;
        JMenuItem menuItem;
        for (String key : map.keySet()) {
            menu = new JMenu(key);
            menu.setMnemonic(key.charAt(0));
            for (String item : map.get(key)) {
                if (GenUtils.isNotBlank(item)) {
                    menuItem = new JMenuItem(item);
                    menuItem.setMnemonic(item.charAt(0));
                    menuItem.addActionListener(this);
                    menu.add(menuItem);
                } else {
                    menu.addSeparator();
                }
            }
            menuBar.add(menu);
        }
        this.setJMenuBar(menuBar);
    }


    /**
     * 初始化选项布局
     */
    private void initChooseBoxPanel() {
        entityBox = new JCheckBox("entity");
        repositoryBox = new JCheckBox("repository");
        serviceBox = new JCheckBox("service");
        serviceImplBox = new JCheckBox("serviceImpl");
        controllerBox = new JCheckBox("controller");
        serviceTestBox = new JCheckBox("serviceTest");
        controllerTestBox = new JCheckBox("controllerTest");
        viewBox = new JCheckBox("views");


        selectAllBox = new JCheckBox("全选");
        selectAllBox.addActionListener(this);

        checkBoxPanel.add(entityBox);
        checkBoxPanel.add(repositoryBox);
        checkBoxPanel.add(serviceBox);
        checkBoxPanel.add(serviceImplBox);
        checkBoxPanel.add(controllerBox);
        checkBoxPanel.add(viewBox);
        checkBoxPanel.add(serviceTestBox);
        checkBoxPanel.add(controllerTestBox);
        checkBoxPanel.add(selectAllBox);
    }


    /**
     * 选择保存的路径
     */
    private void initChooseSavePath() {
        JLabel label = new JLabel("选择保存路径");
        filePathText = new JTextField(60);
        filePathText.setEditable(false);
        filePathText.setText(getProject().getParent().replace('\\','/'));

        bowserDirBtn = new JButton("浏览");
        bowserDirBtn.setSize(60, 30);
        bowserDirBtn.addActionListener(this);

        savePathPanel.add(label);
        savePathPanel.add(filePathText);
        savePathPanel.add(bowserDirBtn);
    }

    /**
     * 初始化编辑器和按钮提示
     */
    private void initEditSql() {
        area=new JTextArea(20,140);
        area.setFont(font);
        area.setSelectedTextColor(Color.RED);
        area.setTabSize(2);
        area.setLineWrap(true);
        area.setWrapStyleWord(true);
        area.setMargin(new Insets(5, 5, 5, 5));
        editSqlPanel.setBackground(Color.GREEN);
        editSqlPanel.setViewportView(area);
        editSqlPanel.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
        area.setCaretPosition(area.getText().length());

    }



    private void initTextFieldPanel(){
        textPanel.setSize(80,30);
        textPanel.setLayout(new FlowLayout(FlowLayout.CENTER,20,5));
        JLabel authorLabel = new JLabel("作者");
        authorText = new JTextField(20);
        authorText.setText(System.getenv().get("COMPUTERNAME"));

        JLabel moduleLabel = new JLabel("模块名称");
        moduleText = new JTextField(10);
        moduleText.setText("base");

        JLabel eltryLabel = new JLabel("入口");
        entry = new JComboBox<>();
        entry.addItem("management");
        entry.addItem("weixin");


        textPanel.add(authorLabel);
        textPanel.add(authorText);
        textPanel.add(moduleLabel);
        textPanel.add(moduleText);
        textPanel.add(eltryLabel);
        textPanel.add(entry);
    }

    private void initOperationPanel(){
        operationPanel.setLayout(new GridLayout(2,4,10,10));
        modalBox = new JCheckBox("是否是modal增加修改");
        //modalBox.setBounds(10, 410, 280, 30);

        treeBox = new JCheckBox("是否是Tree格式");
        //treeBox.setBounds(320, 410, 280, 30);

        btn = new JButton("生成代码");
        btn.setBackground(Color.DARK_GRAY);
        btn.setFont(new Font("宋体",Font.BOLD,14));
        btn.setForeground(Color.WHITE);
       // btn.setBounds(10, 450, 70, 36);
        btn.setFocusPainted(false);
        btn.addActionListener(this);
        btn.setBorder(BorderFactory.createEmptyBorder());

        tips = new JLabel();
        //tips.setBounds(120, 450, 160, 36);

        tableNameText = new JTextField();
        //tableNameText.setBounds(300, 450, 200, 36);

        deleteTableBtn = new JButton();
        deleteTableBtn.setSize(70,136);
        deleteTableBtn.setFont(font);
       // deleteTableBtn.setBounds(520, 450, 70, 36);
        deleteTableBtn.setBorder(BorderFactory.createEmptyBorder());
        deleteTableBtn.setForeground(Color.white);
        deleteTableBtn.setBackground(Color.red);
        deleteTableBtn.setText("删除");
        deleteTableBtn.setFocusPainted(false);
        deleteTableBtn.addActionListener(this);

        operationPanel.add(modalBox);
        operationPanel.add(treeBox);
        operationPanel.add(btn);
        operationPanel.add(tips);

        JLabel lblTableName=new JLabel("数据库表名");
        lblTableName.setForeground(Color.RED);
        operationPanel.add(lblTableName);
        operationPanel.add(tableNameText);
        operationPanel.add(deleteTableBtn);
    }

    /**
     * 初始化布局
     */
    private void initLayout() {
        initMenuBar();
        initTextFieldPanel();
        initChooseBoxPanel();
        initChooseSavePath();
        initEditSql();
        initOperationPanel();
    }


    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == selectAllBox) {
            entityBox.setSelected(selectAllBox.isSelected());
            repositoryBox.setSelected(selectAllBox.isSelected());
            serviceBox.setSelected(selectAllBox.isSelected());
            serviceImplBox.setSelected(selectAllBox.isSelected());
            controllerBox.setSelected(selectAllBox.isSelected());
            serviceTestBox.setSelected(selectAllBox.isSelected());
            controllerTestBox.setSelected(selectAllBox.isSelected());
            viewBox.setSelected(selectAllBox.isSelected());
        }
        if (e.getSource() == btn) {
            tips.setText("开始生成文件");
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        startGen();
                        Thread.sleep(1000);
                    } catch (Exception e) {
                        e.printStackTrace();
                        tips.setText("解析代码出错");
                    }
                }
            }).start();
        }
        if (e.getSource() == bowserDirBtn) {
            initSavePath();
        }

        if (e.getSource() == deleteTableBtn) {

            int m = JOptionPane.showConfirmDialog(null, "你是否要删除表的所有信息么？", "标题", JOptionPane.OK_CANCEL_OPTION);
            if(m==JOptionPane.OK_OPTION){
                deleteFiles();
            }
        }
    }

    /**
     * 初始化选择文件夹路径
     */
    private void initSavePath() {
        JFileChooser jfc = new JFileChooser();
        jfc.setDialogTitle("请选择要生成的目录");
        jfc.setSelectedFile(getProject());
        jfc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
        int result = jfc.showOpenDialog(this);

        if (JFileChooser.APPROVE_OPTION == result) {
            File file = jfc.getSelectedFile();
            if (file.isDirectory()) {
                String path = file.getAbsolutePath();
                filePathText.setText(path);
            } else {
                JOptionPane.showMessageDialog(null, "你选择的目录不存在");
            }
        }
    }

    /**
     * 开始生成
     */
    private void startGen() {
        String sql = area.getText();
        tips.setText("sql 解析中");

        Table table = GenUtils.convert(sql);
        table.setAuthor(authorText.getText());
        PropConfig config=getPropConfig();
        if(config==null){
            return;
        }
        GenerateProject generate = new GenerateProject(table, config);

        if (entityBox.isSelected()) {
            tips.setText("生成Entity");
            generate.genEntity();
        }
        if (repositoryBox.isSelected()) {
            tips.setText("生成Repository");
            generate.genRepo();
        }
        if (serviceBox.isSelected()) {
            tips.setText("生成Service");
            generate.genService();
        }
        if (serviceImplBox.isSelected()) {
            tips.setText("生成ServiceImpl");
            generate.genServiceImpl();
        }
        if (controllerBox.isSelected()) {
            tips.setText("生成controller");
            generate.genController();
        }
        if (serviceTestBox.isSelected()) {
            tips.setText("生成service test");
            generate.genServiceTest();
        }
        if (viewBox.isSelected()) {
            tips.setText("生成view");
            generate.genVue();
        }
        if (controllerTestBox.isSelected()) {
            tips.setText("生成ControllerTest");
            generate.genControllerTest();
        }
        tips.setText("文件生成完成");
    }

    /**
     * 获取当前项目的根目录
     *
     * @return projectFile
     */
    private File getProject() {
        String path = this.getClass().getResource("/").getFile();
        return new File(path).getParentFile().getParentFile();
    }

    /**
     * 删除所有文件
     */
    private void deleteFiles() {
        String author = authorText.getText();
        String module=moduleText.getText();
        String entry=this.entry.getSelectedItem().toString();
        String projectPath= filePathText.getText();
        PropConfig config=new PropConfig(projectPath,entry,author,module);

        String tableName = tableNameText.getText();
        tableName = tableName.substring(0, tableName.length()-1);
        //String clsName = StringUtils.capitalize(tableName); //表名转换为类名
        String clsName= CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL,tableName);

        deleteFile(new File(config.getEntityPath()+clsName+".java"));
        deleteFile(new File(config.getRepositoryPath()+clsName+"Repository.java"));
        deleteFile(new File(config.getServicePath()+clsName+"Service.java"));
        deleteFile(new File(config.getServiceImplPath()+clsName+"ServiceImpl.java"));
        deleteFile(new File(config.getControllerPath()+clsName+"sController.java"));
        deleteFile(new File(config.getServiceTestPath()+clsName+"ServiceTest.java"));
        deleteFile(new File(config.getControllerTestConfigPath()+clsName+"ControllerTestConfiguration.java"));
        deleteFile(new File(config.getControllerTestPath()+clsName+"ControllerTest.java"));
        //删除vue 视图文件夹
        deleteFile(new File(config.getVuePath()+StringUtils.uncapitalize(clsName)+"s"));
        //删除vue 路由
        deleteFile(new File(config.getVueRouterPath()+StringUtils.uncapitalize(clsName)+".router"));


    }

    private boolean deleteFile(File file){
        if(file.exists()){
            if(file.isDirectory()){
                try {
                     FileUtils.deleteDirectory(file);
                    log.info("删除文件夹"+file.getAbsolutePath());
                    return true;
                } catch (IOException e) {
                    e.printStackTrace();
                    return false;
                }

            }
            boolean result=file.delete();
            log.info("删除:"+file.getAbsolutePath());
            return result;
        }else{
            log.error(file.getAbsolutePath()+"不存在！");
        }
        return false;
    }

    private PropConfig getPropConfig(){
        //检查配置项
        String author = authorText.getText();
        if (StringUtils.isBlank(author)) {
            JOptionPane.showMessageDialog(null, "需要输入作者", "错误", JOptionPane.ERROR_MESSAGE);
            return null;
        }
        String module=moduleText.getText();
        if (StringUtils.isBlank(module)) {
            JOptionPane.showMessageDialog(null, "需要输入模块名称", "错误", JOptionPane.ERROR_MESSAGE);
            return null;
        }

        String entry=this.entry.getSelectedItem().toString();
        if (StringUtils.isBlank(entry)) {
            JOptionPane.showMessageDialog(null, "需要选择入口", "错误", JOptionPane.ERROR_MESSAGE);
            return null;
        }
        String projectPath= filePathText.getText();

        PropConfig config=new PropConfig(projectPath,entry,author,module);
        config.setTree(treeBox.isSelected());
        config.setModal(modalBox.isSelected());
        return config;
    }
}